<!--
圆形扫描
 -->
<template>
  <div class="container">
    <div id="cesiumContainer"> </div>
  </div>
</template>

<script>
  export default {
    name: "cesiumviewer",
    data() {
      return {
        viewer: {},
      }
    },
    mounted() {
      var Cesium = this.Cesium;
      this.viewer = new Cesium.Viewer("cesiumContainer", {
        animation: false, // 是否显示动画控件
        homeButton: false, // 是否显示home键
        geocoder: false, // 是否显示地名查找控件
        baseLayerPicker: false, // 是否显示图层选择控件
        timeline: false, // 是否显示时间线控件
        fullscreenButton: true, // 是否全屏显示
        infoBox: true, // 是否显示点击要素之后显示的信息
        sceneModePicker: false, // 是否显示投影方式控件  三维/二维
        navigationInstructionsInitiallyVisible: false,
        navigationHelpButton: false, // 是否显示帮助信息控件
        orderIndependentTranslucency: false,
        shouldAnimate: true,
        scene3DOnly: false, // 每个几何实例将只能以3D渲染以节省GPU内存
        selectionIndicator: false // 取消点击有绿框
      });
      this.viewer._cesiumWidget._creditContainer.style.display = "none"; //隐藏ceisum标识
      //this.viewer.cesiumWidget.creditContainer.style.display = 'none'; //隐藏ceisum标识

      this.addCircleScan({
        lon: 113.27, //经度
        lat: 23.13, //纬度
        scanColor: new Cesium.Color(0, 1, 0, 1),
        r: 500, //扫描半径
        interval: 3000 //时间间隔
      });
      //飞行到这个位子
      this.viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(113.27, 23.13, 1500.0),
        orientation: {
          heading: 0, //Cesium.Math.toRadians(90.0), // east, default value is 0.0 (north) //东西南北朝向
          pitch: Cesium.Math.toRadians(-90), // default value (looking down)  //俯视仰视视觉
          roll: 0.0 // default value
        },
        duration: 3 //3秒到达战场
      });

    },
    methods: {
      /** from
       * @author 跃焱邵隼
       * time 2019
       * blog:www.wellyyss.cn
       * qq/wx:571475926
       * qq group: 169470811
       */
      addCircleScan(data) {
        var Cesium = this.Cesium;
        this.viewer.scene.globe.depthTestAgainstTerrain =
          true; //防止移动、放大缩小会视觉偏移depthTestAgainstTerrain // 设置该属性为true之后，标绘将位于地形的顶部；如果设为false（默认值），那么标绘将位于平面上。缺陷：开启该属性有可能在切换图层时会引发标绘消失的bug。
        const CartographicCenter = new Cesium.Cartographic(Cesium.Math.toRadians(data.lon), Cesium.Math.toRadians(data
          .lat), 0); //中心位子
        return this.addCircleScanPostStage(this.viewer, CartographicCenter, data.r, data.scanColor, data.interval);
      },
      addCircleScanPostStage(viewer, cartographicCenter, maxRadius, scanColor, duration) {
        const ScanSegmentShader =
          "uniform sampler2D colorTexture;" +
          "uniform sampler2D depthTexture;" +
          "varying vec2 v_textureCoordinates;" +
          "uniform vec4 u_scanCenterEC;" +
          "uniform vec3 u_scanPlaneNormalEC;" +
          "uniform float u_radius;" +
          "uniform vec4 u_scanColor;" +
          "vec4 toEye(in vec2 uv, in float depth)" +
          " {" +
          " vec2 xy = vec2((uv.x * 2.0 - 1.0),(uv.y * 2.0 - 1.0));" +
          " vec4 posInCamera =czm_inverseProjection * vec4(xy, depth, 1.0);" +
          " posInCamera =posInCamera / posInCamera.w;" +
          " return posInCamera;" +
          " }" +
          "vec3 pointProjectOnPlane(in vec3 planeNormal, in vec3 planeOrigin, in vec3 point)" +
          "{" +
          "vec3 v01 = point -planeOrigin;" +
          "float d = dot(planeNormal, v01) ;" +
          "return (point - planeNormal * d);" +
          "}" +
          "float getDepth(in vec4 depth)" +
          "{" +
          "float z_window = czm_unpackDepth(depth);" +
          "z_window = czm_reverseLogDepth(z_window);" +
          "float n_range = czm_depthRange.near;" +
          "float f_range = czm_depthRange.far;" +
          "return (2.0 * z_window - n_range - f_range) / (f_range - n_range);" +
          "}" +
          "void main()" +
          "{" +
          "gl_FragColor = texture2D(colorTexture, v_textureCoordinates);" +
          "float depth = getDepth( texture2D(depthTexture, v_textureCoordinates));" +
          "vec4 viewPos = toEye(v_textureCoordinates, depth);" +
          "vec3 prjOnPlane = pointProjectOnPlane(u_scanPlaneNormalEC.xyz, u_scanCenterEC.xyz, viewPos.xyz);" +
          "float dis = length(prjOnPlane.xyz - u_scanCenterEC.xyz);" +
          "if(dis < u_radius)" +
          "{" +
          "float f = 1.0 -abs(u_radius - dis) / u_radius;" +
          "f = pow(f, 4.0);" +
          "gl_FragColor = mix(gl_FragColor, u_scanColor, f);" +
          "}" +
          "}";
        let Cesium = this.Cesium;
        const _Cartesian3Center = Cesium.Cartographic.toCartesian(cartographicCenter);
        const _Cartesian4Center = new Cesium.Cartesian4(_Cartesian3Center.x, _Cartesian3Center.y, _Cartesian3Center.z,
          1);
        const _CartographicCenter1 = new Cesium.Cartographic(cartographicCenter.longitude, cartographicCenter.latitude,
          cartographicCenter.height + 500);
        const _Cartesian3Center1 = Cesium.Cartographic.toCartesian(_CartographicCenter1);
        const _Cartesian4Center1 = new Cesium.Cartesian4(_Cartesian3Center1.x, _Cartesian3Center1.y, _Cartesian3Center1
          .z, 1);
        const _time = (new Date()).getTime();
        const _scratchCartesian4Center = new Cesium.Cartesian4();
        const _scratchCartesian4Center1 = new Cesium.Cartesian4();
        const _scratchCartesian3Normal = new Cesium.Cartesian3();
        const ScanPostStage = new Cesium.PostProcessStage({
          fragmentShader: ScanSegmentShader,
          uniforms: {
            u_scanCenterEC: function() {
              return Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center,
                _scratchCartesian4Center);
            },
            u_scanPlaneNormalEC: function() {
              const temp = Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center,
                _scratchCartesian4Center);
              const temp1 = Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center1,
                _scratchCartesian4Center1);
              _scratchCartesian3Normal.x = temp1.x - temp.x;
              _scratchCartesian3Normal.y = temp1.y - temp.y;
              _scratchCartesian3Normal.z = temp1.z - temp.z;
              Cesium.Cartesian3.normalize(_scratchCartesian3Normal, _scratchCartesian3Normal);
              return _scratchCartesian3Normal;

            },
            u_radius: function() {
              return maxRadius * (((new Date()).getTime() - _time) % duration) / duration;
            },
            u_scanColor: scanColor
          }
        });
        viewer.scene.postProcessStages.add(ScanPostStage)
        return ScanPostStage
      }
    }
  }
</script>

<style scoped="scoped">
  .container {
    width: 100%;
    height: 100%;
  }

  #cesiumContainer {
    width: 100%;
    height: 100%;
    position: absolute;
    margin: 0;
    padding: 0;
    /*  overflow: hidden; */
  }
</style>
